//
// PowerUp - Fountains adventure screen object handler
//
// L. Dean Gibson II 2/9/01
//
//

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_fountain.h"
#include "adv_object_type.h"
#include "adventure_sounds.h"
#include "ai_value.h"
#include "army.h"
#include "basic_dialog.h"
#include "creature.h"
#include "creature_stack.h"
#include "external_string.h"
#include "hero.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "replace_keywords.h"
#include "simple_dialog.h"


static t_object_registration<t_adv_fountain> k_registration( k_adv_object_fountain );

namespace {
	
	float ai_additional_hit_point_value( t_hero const* hero )
	{
		int bonus = (int)(hero->get_hit_points() * 0.2f);
		if (bonus < 12) 
			bonus = 12; 
		return ai_value_of_additional_hit_points( hero, bonus );
	}

	float ai_additional_damage_value( t_hero const* hero )
	{
		float archery_value = (float)hero->get_damage_low( true ) * 0.2;
		float combat_value = (float)hero->get_damage_low( false ) * 0.2;
		float low_value, high_value;
		if (archery_value > combat_value) 
		{
			low_value = archery_value;
			high_value = hero->get_damage_high( true ) * 0.2;
			return ai_value_of_additional_damage( hero, true, low_value, high_value );
		} 
		else
		{
			low_value = combat_value;
			high_value = hero->get_damage_high( false ) * 0.2;

			return ai_value_of_additional_damage( hero, false, low_value, high_value );
		}
	}
};

// -------------------------------------------------------
// fountain object constructor
// -------------------------------------------------------
t_adv_fountain::t_adv_fountain(  std::string const& source )
			  : t_stationary_adventure_object( source )
{

}

// -------------------------------------------------------
// activate trigger for the fountain adventure map object
// -------------------------------------------------------

void t_adv_fountain::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                               t_direction direction, t_adventure_frame* frame )
{
	int					 fountain_type;
	int                  i;
	t_hero*              hero;
	std::vector<t_hero*> heroes;
	bool				 any_heroes = false;
	bool                 any_benefit = false;
	bool                 added_icon = false;

	// loop through all heroes/creatures in the army and award temporary statistic based on subtype
	fountain_type = get_type().major_subtype();

	t_creature_array& creatures = army->get_creatures();

    t_counted_ptr<t_basic_dialog> dialog_ptr;
	dialog_ptr = new t_basic_dialog;
	dialog_ptr->set_title( get_name() );

	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero = creatures[i].get_hero();
		if ((hero == 0) || hero->is_dead()) // it must be a creature
			continue;

		any_heroes = true;

		switch (fountain_type) {
			case k_fountain_of_strength: // add 20% to damage low and high
				any_benefit = !hero->is_spell_active( k_spell_strength );
    			hero->set_spell( k_spell_strength );
                if (any_benefit && (!added_icon))
                {
                    dialog_ptr->add_damage( 20, 20, true );
	                added_icon = true;
                }
				break;

			case k_fountain_spring_of_speed: // +2 speed
				any_benefit = !hero->is_spell_active( k_spell_speed );
				hero->set_spell( k_spell_speed );
                if (any_benefit && (!added_icon))
                {
                    dialog_ptr->add_speed( 2 );
	                added_icon = true;
                }
				break;

			case k_fountain_of_vigor: // add 20% hit points
				any_benefit = !hero->is_spell_active( k_spell_health_boost );
				hero->set_spell( k_spell_health_boost );
                if (any_benefit && (!added_icon))
                {
                    dialog_ptr->add_hit_points( 20, true );
	                added_icon = true;
                }
				break;

			case k_fountain_pool_of_power:// add 20% damage and hit points
				any_benefit = !hero->is_spell_active( k_spell_strength ) 
					       || !hero->is_spell_active( k_spell_health_boost );
				hero->set_spell( k_spell_strength );
				hero->set_spell( k_spell_health_boost );
                if (any_benefit && (!added_icon))
                {
                    dialog_ptr->add_damage( 20, 20, true );
                    dialog_ptr->add_hit_points( 20, true );
	                added_icon = true;
                }
				break;
		}
	}

	// determine what response to print
	if (army->get_owner()->is_computer())
		return;

	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_mana )->play( get_sound_volume() );

    std::string text;
            
	text = get_text( "initial" );

	if (!any_heroes)
	{
		//ok_dialog( get_text( "no_heroes" ), get_dialog_bottom( point ));
		text = get_text( "no_heroes" );
	}
	else
		if ( !any_benefit  ) 
		{
			//ok_dialog( get_text( "empty" ), get_dialog_bottom( point ));
			text =  get_text( "empty" );
		}

	//ok_dialog( get_text( "initial" ), get_dialog_bottom( point ));
	dialog_ptr->set_text( text );
	dialog_ptr->add_ok_button();
	dialog_ptr->open( get_dialog_bottom( point ), true, k_align_bottom );
	dialog_ptr->run_modal();

	play_music( music );
}

float t_adv_fountain::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	int fountain_type = get_type().major_subtype();
	float total_value = 0.0f;
	for (int i = 0; i < t_creature_array::k_size; i++)
	{
		t_creature_stack const& stack = army[i];
		t_hero const* hero = stack.get_const_hero();
		if ( !hero  )
			continue;
		
		switch (fountain_type) {
			case k_fountain_of_strength: 
				if (!hero->is_spell_active( k_spell_strength ))
					total_value += ai_additional_damage_value( hero );
				break;

			case k_fountain_spring_of_speed: 
				if (!hero->is_spell_active( k_spell_speed ))
					total_value += ai_value_of_additional_speed( hero, 2 );
				break;

			case k_fountain_of_vigor: 
				if (!hero->is_spell_active( k_spell_health_boost ))
					total_value += ai_additional_hit_point_value( hero );
				break;

			case k_fountain_pool_of_power:
				if (!hero->is_spell_active( k_spell_strength ))
					total_value += ai_additional_damage_value( hero );
				if (!hero->is_spell_active( k_spell_health_boost ))
					total_value += ai_additional_hit_point_value( hero );
				break;
			default: 
				assert(false);
		}
	}
	return total_value;
}
